Completed
Push — master ( 2e96ee...51b9e4 )
by Rain
01:37
created

ComposePopupView.onMessageUploadAttachments   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 5
nc 3
nop 2
dl 0
loc 22
rs 8.6737
c 1
b 1
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
A 0 8 2
1
2
var
3
	window = require('window'),
4
	_ = require('_'),
5
	$ = require('$'),
6
	ko = require('ko'),
7
	key = require('key'),
8
	JSON = require('JSON'),
0 ignored issues
show
Comprehensibility introduced by
You are shadowing the built-in type JSON. This makes code hard to read, consider using a different name.
Loading history...
9
	Jua = require('Jua'),
10
11
	Enums = require('Common/Enums'),
12
	Consts = require('Common/Consts'),
13
	Utils = require('Common/Utils'),
14
	Globals = require('Common/Globals'),
15
	Events = require('Common/Events'),
16
	Links = require('Common/Links'),
17
	HtmlEditor = require('Common/HtmlEditor').default,
18
19
	Translator = require('Common/Translator'),
20
	Momentor = require('Common/Momentor'),
21
22
	Cache = require('Common/Cache'),
23
24
	AppStore = require('Stores/User/App'),
25
	SettingsStore = require('Stores/User/Settings'),
26
	IdentityStore = require('Stores/User/Identity'),
27
	AccountStore = require('Stores/User/Account'),
28
	FolderStore = require('Stores/User/Folder'),
29
	PgpStore = require('Stores/User/Pgp'),
30
	MessageStore = require('Stores/User/Message'),
31
	SocialStore = require('Stores/Social'),
32
33
	Settings = require('Storage/Settings'),
34
	Remote = require('Remote/User/Ajax'),
35
36
	ComposeAttachmentModel = require('Model/ComposeAttachment').default,
37
38
	kn = require('Knoin/Knoin'),
39
	AbstractView = require('Knoin/AbstractView');
40
41
/**
42
 * @constructor
43
 * @extends AbstractView
44
 */
45
function ComposePopupView()
46
{
47
	AbstractView.call(this, 'Popups', 'PopupsCompose');
48
49
	var
50
		self = this,
51
		fEmailOutInHelper = function(context, oIdentity, sName, bIn) {
52
			if (oIdentity && context && oIdentity[sName]() && (bIn ? true : context[sName]()))
53
			{
54
				var
55
					sIdentityEmail = oIdentity[sName](),
56
					aList = Utils.trim(context[sName]()).split(/[,]/);
57
58
				aList = _.filter(aList, function(sEmail) {
59
					sEmail = Utils.trim(sEmail);
60
					return sEmail && Utils.trim(sIdentityEmail) !== sEmail;
61
				});
62
63
				if (bIn)
64
				{
65
					aList.push(sIdentityEmail);
66
				}
67
68
				context[sName](aList.join(','));
69
			}
70
		};
71
72
	this.oLastMessage = null;
73
	this.oEditor = null;
74
	this.aDraftInfo = null;
75
	this.sInReplyTo = '';
76
	this.bFromDraft = false;
77
	this.sReferences = '';
78
79
	this.sLastFocusedField = 'to';
80
81
	this.resizerTrigger = _.bind(this.resizerTrigger, this);
82
83
	this.allowContacts = !!AppStore.contactsIsAllowed();
84
	this.allowFolders = !!Settings.capa(Enums.Capa.Folders);
85
86
	this.bSkipNextHide = false;
87
	this.composeInEdit = AppStore.composeInEdit;
88
	this.editorDefaultType = SettingsStore.editorDefaultType;
89
90
	this.capaOpenPGP = PgpStore.capaOpenPGP;
91
92
	this.identitiesDropdownTrigger = ko.observable(false);
93
94
	this.to = ko.observable('');
95
	this.to.focused = ko.observable(false);
96
	this.cc = ko.observable('');
97
	this.cc.focused = ko.observable(false);
98
	this.bcc = ko.observable('');
99
	this.bcc.focused = ko.observable(false);
100
	this.replyTo = ko.observable('');
101
	this.replyTo.focused = ko.observable(false);
102
103
	ko.computed(function() {
104
		switch (true)
105
		{
106
			case this.to.focused():
107
				this.sLastFocusedField = 'to';
108
				break;
109
			case this.cc.focused():
110
				this.sLastFocusedField = 'cc';
111
				break;
112
			case this.bcc.focused():
113
				this.sLastFocusedField = 'bcc';
114
				break;
115
			// no default
116
		}
117
	}, this).extend({'notify': 'always'});
118
119
	this.subject = ko.observable('');
120
	this.subject.focused = ko.observable(false);
121
122
	this.isHtml = ko.observable(false);
123
124
	this.requestDsn = ko.observable(false);
125
	this.requestReadReceipt = ko.observable(false);
126
	this.markAsImportant = ko.observable(false);
127
128
	this.sendError = ko.observable(false);
129
	this.sendSuccessButSaveError = ko.observable(false);
130
	this.savedError = ko.observable(false);
131
132
	this.sendButtonSuccess = ko.computed(function() {
133
		return !this.sendError() && !this.sendSuccessButSaveError();
134
	}, this);
135
136
	this.sendErrorDesc = ko.observable('');
137
	this.savedErrorDesc = ko.observable('');
138
139
	this.sendError.subscribe(function(bValue) {
140
		if (!bValue)
141
		{
142
			this.sendErrorDesc('');
143
		}
144
	}, this);
145
146
	this.savedError.subscribe(function(bValue) {
147
		if (!bValue)
148
		{
149
			this.savedErrorDesc('');
150
		}
151
	}, this);
152
153
	this.sendSuccessButSaveError.subscribe(function(bValue) {
154
		if (!bValue)
155
		{
156
			this.savedErrorDesc('');
157
		}
158
	}, this);
159
160
	this.savedTime = ko.observable(0);
161
	this.savedTimeText = ko.computed(function() {
162
		return 0 < this.savedTime() ? Translator.i18n('COMPOSE/SAVED_TIME', {
163
			'TIME': Momentor.format(this.savedTime() - 1, 'LT')
164
		}) : '';
165
	}, this);
166
167
	this.emptyToError = ko.observable(false);
168
	this.emptyToErrorTooltip = ko.computed(function() {
169
		return this.emptyToError() ? Translator.i18n('COMPOSE/EMPTY_TO_ERROR_DESC') : '';
170
	}, this);
171
172
	this.attachmentsInProcessError = ko.observable(false);
173
	this.attachmentsInErrorError = ko.observable(false);
174
175
	this.attachmentsErrorTooltip = ko.computed(function() {
176
177
		var sResult = '';
178
		switch (true)
179
		{
180
			case this.attachmentsInProcessError():
181
				sResult = Translator.i18n('COMPOSE/ATTACHMENTS_UPLOAD_ERROR_DESC');
182
				break;
183
			case this.attachmentsInErrorError():
184
				sResult = Translator.i18n('COMPOSE/ATTACHMENTS_ERROR_DESC');
185
				break;
186
			// no default
187
		}
188
189
		return sResult;
190
191
	}, this);
192
193
	this.showCc = ko.observable(false);
194
	this.showBcc = ko.observable(false);
195
	this.showReplyTo = ko.observable(false);
196
197
	this.cc.subscribe(function(aValue) {
198
		if (false === self.showCc() && 0 < aValue.length)
199
		{
200
			self.showCc(true);
201
		}
202
	}, this);
203
204
	this.bcc.subscribe(function(aValue) {
205
		if (false === self.showBcc() && 0 < aValue.length)
206
		{
207
			self.showBcc(true);
208
		}
209
	}, this);
210
211
	this.replyTo.subscribe(function(aValue) {
212
		if (false === self.showReplyTo() && 0 < aValue.length)
213
		{
214
			self.showReplyTo(true);
215
		}
216
	}, this);
217
218
	this.draftFolder = ko.observable('');
219
	this.draftUid = ko.observable('');
220
	this.sending = ko.observable(false);
221
	this.saving = ko.observable(false);
222
	this.attachments = ko.observableArray([]);
223
224
	this.attachmentsInProcess = this.attachments.filter(function(oItem) {
225
		return oItem && !oItem.complete();
226
	});
227
228
	this.attachmentsInReady = this.attachments.filter(function(oItem) {
229
		return oItem && oItem.complete();
230
	});
231
232
	this.attachmentsInError = this.attachments.filter(function(oItem) {
233
		return oItem && '' !== oItem.error();
234
	});
235
236
	this.attachmentsCount = ko.computed(function() {
237
		return this.attachments().length;
238
	}, this);
239
240
	this.attachmentsInErrorCount = ko.computed(function() {
241
		return this.attachmentsInError().length;
242
	}, this);
243
244
	this.attachmentsInProcessCount = ko.computed(function() {
245
		return this.attachmentsInProcess().length;
246
	}, this);
247
248
	this.isDraftFolderMessage = ko.computed(function() {
249
		return '' !== this.draftFolder() && '' !== this.draftUid();
250
	}, this);
251
252
	this.attachmentsPlace = ko.observable(false);
253
254
	this.attachments.subscribe(this.resizerTrigger);
255
	this.attachmentsPlace.subscribe(this.resizerTrigger);
256
257
	this.attachmentsInErrorCount.subscribe(function(iN) {
258
		if (0 === iN)
259
		{
260
			this.attachmentsInErrorError(false);
261
		}
262
	}, this);
263
264
	this.composeUploaderButton = ko.observable(null);
265
	this.composeUploaderDropPlace = ko.observable(null);
266
	this.dragAndDropEnabled = ko.observable(false);
267
	this.dragAndDropOver = ko.observable(false).extend({'throttle': 1});
268
	this.dragAndDropVisible = ko.observable(false).extend({'throttle': 1});
269
	this.attacheMultipleAllowed = ko.observable(false);
270
	this.addAttachmentEnabled = ko.observable(false);
271
272
	this.composeEditorArea = ko.observable(null);
273
274
	this.identities = IdentityStore.identities;
275
	this.identitiesOptions = ko.computed(function() {
276
		return _.map(IdentityStore.identities(), function(oItem) {
277
			return {
278
				'item': oItem,
279
				'optValue': oItem.id(),
280
				'optText': oItem.formattedName()
281
			};
282
		});
283
	}, this);
284
285
	this.currentIdentity = ko.observable(
286
		this.identities()[0] ? this.identities()[0] : null);
287
288
	this.currentIdentity.extend({'toggleSubscribe': [this,
289
		function(oIdentity) {
290
			fEmailOutInHelper(this, oIdentity, 'bcc');
291
			fEmailOutInHelper(this, oIdentity, 'replyTo');
292
		}, function(oIdentity) {
293
			fEmailOutInHelper(this, oIdentity, 'bcc', true);
294
			fEmailOutInHelper(this, oIdentity, 'replyTo', true);
295
		}
296
	]});
297
298
	this.currentIdentityView = ko.computed(function() {
299
		var oItem = this.currentIdentity();
300
		return oItem ? oItem.formattedName() : 'unknown';
301
	}, this);
302
303
	this.to.subscribe(function(sValue) {
304
		if (this.emptyToError() && 0 < sValue.length)
305
		{
306
			this.emptyToError(false);
307
		}
308
	}, this);
309
310
	this.attachmentsInProcess.subscribe(function(aValue) {
311
		if (this.attachmentsInProcessError() && Utils.isArray(aValue) && 0 === aValue.length)
312
		{
313
			this.attachmentsInProcessError(false);
314
		}
315
	}, this);
316
317
	this.resizer = ko.observable(false).extend({'throttle': 50});
318
319
	this.resizer.subscribe(_.bind(function() {
320
		if (this.oEditor) {
321
			this.oEditor.resize();
322
		}
323
	}, this));
324
325
	this.canBeSentOrSaved = ko.computed(function() {
326
		return !this.sending() && !this.saving();
327
	}, this);
328
329
	this.deleteCommand = Utils.createCommand(this, function() {
330
331
		var
332
			PopupsAskViewModel = require('View/Popup/Ask');
333
334
		if (!kn.isPopupVisible(PopupsAskViewModel) && this.modalVisibility())
335
		{
336
			kn.showScreenPopup(PopupsAskViewModel, [Translator.i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'), function() {
337
				if (self.modalVisibility())
338
				{
339
					require('App/User').default.deleteMessagesFromFolderWithoutCheck(self.draftFolder(), [self.draftUid()]);
340
					kn.hideScreenPopup(ComposePopupView);
341
				}
342
			}]);
343
		}
344
345
	}, function() {
346
		return this.isDraftFolderMessage();
347
	});
348
349
	this.sendMessageResponse = _.bind(this.sendMessageResponse, this);
350
	this.saveMessageResponse = _.bind(this.saveMessageResponse, this);
351
352
	this.sendCommand = Utils.createCommand(this, function() {
353
354
		var
355
			sTo = Utils.trim(this.to()),
356
			sCc = Utils.trim(this.cc()),
357
			sBcc = Utils.trim(this.bcc()),
358
			sSentFolder = FolderStore.sentFolder();
359
360
		this.attachmentsInProcessError(false);
361
		this.attachmentsInErrorError(false);
362
		this.emptyToError(false);
363
364
		if (0 < this.attachmentsInProcess().length)
365
		{
366
			this.attachmentsInProcessError(true);
367
			this.attachmentsPlace(true);
368
		}
369
		else if (0 < this.attachmentsInError().length)
370
		{
371
			this.attachmentsInErrorError(true);
372
			this.attachmentsPlace(true);
373
		}
374
375
		if ('' === sTo && '' === sCc && '' === sBcc)
376
		{
377
			this.emptyToError(true);
378
		}
379
380
		if (!this.emptyToError() && !this.attachmentsInErrorError() && !this.attachmentsInProcessError())
381
		{
382
			if (SettingsStore.replySameFolder())
383
			{
384
				if (Utils.isArray(this.aDraftInfo) && 3 === this.aDraftInfo.length && Utils.isNormal(this.aDraftInfo[2]) && 0 < this.aDraftInfo[2].length)
385
				{
386
					sSentFolder = this.aDraftInfo[2];
387
				}
388
			}
389
390
			if (!this.allowFolders)
391
			{
392
				sSentFolder = Consts.UNUSED_OPTION_VALUE;
393
			}
394
395
			if ('' === sSentFolder)
396
			{
397
				kn.showScreenPopup(require('View/Popup/FolderSystem'), [Enums.SetSystemFoldersNotification.Sent]);
398
			}
399
			else
400
			{
401
				this.sendError(false);
402
				this.sending(true);
403
404
				if (Utils.isArray(this.aDraftInfo) && 3 === this.aDraftInfo.length)
405
				{
406
					var aFlagsCache = Cache.getMessageFlagsFromCache(this.aDraftInfo[2], this.aDraftInfo[1]);
407
					if (aFlagsCache)
408
					{
409
						if ('forward' === this.aDraftInfo[0])
410
						{
411
							aFlagsCache[3] = true;
412
						}
413
						else
414
						{
415
							aFlagsCache[2] = true;
416
						}
417
418
						Cache.setMessageFlagsToCache(this.aDraftInfo[2], this.aDraftInfo[1], aFlagsCache);
419
						require('App/User').default.reloadFlagsCurrentMessageListAndMessageFromCache();
420
						Cache.setFolderHash(this.aDraftInfo[2], '');
421
					}
422
				}
423
424
				sSentFolder = Consts.UNUSED_OPTION_VALUE === sSentFolder ? '' : sSentFolder;
425
426
				Cache.setFolderHash(this.draftFolder(), '');
427
				Cache.setFolderHash(sSentFolder, '');
428
429
				Remote.sendMessage(
430
					this.sendMessageResponse,
431
					this.currentIdentity() ? this.currentIdentity().id() : '',
432
					this.draftFolder(),
433
					this.draftUid(),
434
					sSentFolder,
435
					sTo,
436
					this.cc(),
437
					this.bcc(),
438
					this.replyTo(),
439
					this.subject(),
440
					this.oEditor ? this.oEditor.isHtml() : false,
441
					this.oEditor ? this.oEditor.getData(true, true) : '',
442
					this.prepearAttachmentsForSendOrSave(),
443
					this.aDraftInfo,
444
					this.sInReplyTo,
445
					this.sReferences,
446
					this.requestDsn(),
447
					this.requestReadReceipt(),
448
					this.markAsImportant()
449
				);
450
			}
451
		}
452
453
	}, this.canBeSentOrSaved);
454
455
	this.saveCommand = Utils.createCommand(this, function() {
456
457
		if (!this.allowFolders)
458
		{
459
			return false;
460
		}
461
462
		if (FolderStore.draftFolderNotEnabled())
463
		{
464
			kn.showScreenPopup(require('View/Popup/FolderSystem'), [Enums.SetSystemFoldersNotification.Draft]);
465
		}
466
		else
467
		{
468
			this.savedError(false);
469
			this.saving(true);
470
471
			this.autosaveStart();
472
473
			Cache.setFolderHash(FolderStore.draftFolder(), '');
474
475
			Remote.saveMessage(
476
				this.saveMessageResponse,
477
				this.currentIdentity() ? this.currentIdentity().id() : '',
478
				this.draftFolder(),
479
				this.draftUid(),
480
				FolderStore.draftFolder(),
481
				this.to(),
482
				this.cc(),
483
				this.bcc(),
484
				this.replyTo(),
485
				this.subject(),
486
				this.oEditor ? this.oEditor.isHtml() : false,
487
				this.oEditor ? this.oEditor.getData(true) : '',
488
				this.prepearAttachmentsForSendOrSave(),
489
				this.aDraftInfo,
490
				this.sInReplyTo,
491
				this.sReferences,
492
				this.markAsImportant()
493
			);
494
		}
495
496
		return true;
497
498
	}, this.canBeSentOrSaved);
499
500
	this.skipCommand = Utils.createCommand(this, function() {
501
502
		this.bSkipNextHide = true;
503
504
		if (this.modalVisibility() && !this.saving() && !this.sending() &&
505
			!FolderStore.draftFolderNotEnabled())
506
		{
507
			this.saveCommand();
508
		}
509
510
		this.tryToClosePopup();
511
512
	}, this.canBeSentOrSaved);
513
514
	this.contactsCommand = Utils.createCommand(this, function() {
515
516
		if (this.allowContacts)
517
		{
518
			this.skipCommand();
519
			_.delay(function() {
520
				kn.showScreenPopup(require('View/Popup/Contacts'),
521
					[true, self.sLastFocusedField]);
522
			}, Enums.Magics.Time200ms);
523
		}
524
525
	}, function() {
526
		return this.allowContacts;
527
	});
528
529
	Events.sub('interval.2m', function() {
530
531
		if (this.modalVisibility() && !FolderStore.draftFolderNotEnabled() && !this.isEmptyForm(false) &&
532
			!this.saving() && !this.sending() && !this.savedError())
533
		{
534
			this.saveCommand();
535
		}
536
	}, this);
537
538
	this.showCc.subscribe(this.resizerTrigger);
539
	this.showBcc.subscribe(this.resizerTrigger);
540
	this.showReplyTo.subscribe(this.resizerTrigger);
541
542
	this.dropboxEnabled = SocialStore.dropbox.enabled;
543
	this.dropboxApiKey = SocialStore.dropbox.apiKey;
544
545
	this.dropboxCommand = Utils.createCommand(this, function() {
546
547
		if (window.Dropbox)
548
		{
549
			window.Dropbox.choose({
550
				'success': function(files) {
551
					if (files && files[0] && files[0].link)
552
					{
553
						self.addDropboxAttachment(files[0]);
554
					}
555
				},
556
				'linkType': 'direct',
557
				'multiselect': false
558
			});
559
		}
560
561
		return true;
562
563
	}, function() {
564
		return this.dropboxEnabled();
565
	});
566
567
	this.driveEnabled = ko.observable(Globals.bXMLHttpRequestSupported &&
568
		!!Settings.settingsGet('AllowGoogleSocial') && !!Settings.settingsGet('AllowGoogleSocialDrive') &&
569
		!!Settings.settingsGet('GoogleClientID') && !!Settings.settingsGet('GoogleApiKey'));
570
571
	this.driveVisible = ko.observable(false);
572
573
	this.driveCommand = Utils.createCommand(this, function() {
574
575
		this.driveOpenPopup();
576
		return true;
577
578
	}, function() {
579
		return this.driveEnabled();
580
	});
581
582
	this.driveCallback = _.bind(this.driveCallback, this);
583
584
	this.onMessageUploadAttachments = _.bind(this.onMessageUploadAttachments, this);
585
586
	this.bDisabeCloseOnEsc = true;
587
	this.sDefaultKeyScope = Enums.KeyState.Compose;
588
589
	this.tryToClosePopup = _.debounce(_.bind(this.tryToClosePopup, this), Enums.Magics.Time200ms);
590
591
	this.emailsSource = _.bind(this.emailsSource, this);
592
	this.autosaveFunction = _.bind(this.autosaveFunction, this);
593
594
	this.iTimer = 0;
595
596
	kn.constructorEnd(this);
597
}
598
599
kn.extendAsViewModel(['View/Popup/Compose', 'PopupsComposeViewModel'], ComposePopupView);
600
_.extend(ComposePopupView.prototype, AbstractView.prototype);
601
602
ComposePopupView.prototype.autosaveFunction = function()
603
{
604
	if (this.modalVisibility() && !FolderStore.draftFolderNotEnabled() && !this.isEmptyForm(false) &&
605
		!this.saving() && !this.sending() && !this.savedError())
606
	{
607
		this.saveCommand();
608
	}
609
610
	this.autosaveStart();
611
};
612
613
ComposePopupView.prototype.autosaveStart = function()
614
{
615
	window.clearTimeout(this.iTimer);
616
	this.iTimer = window.setTimeout(this.autosaveFunction, Enums.Magics.Time1m);
617
};
618
619
ComposePopupView.prototype.autosaveStop = function()
620
{
621
	window.clearTimeout(this.iTimer);
622
};
623
624
ComposePopupView.prototype.emailsSource = function(oData, fResponse)
625
{
626
	require('App/User').default.getAutocomplete(oData.term, function(aData) {
627
		fResponse(_.map(aData, function(oEmailItem) {
628
			return oEmailItem.toLine(false);
629
		}));
630
	});
631
};
632
633
ComposePopupView.prototype.openOpenPgpPopup = function()
634
{
635
	if (PgpStore.capaOpenPGP() && this.oEditor && !this.oEditor.isHtml())
636
	{
637
		var self = this;
638
		kn.showScreenPopup(require('View/Popup/ComposeOpenPgp'), [
639
			function(sResult) {
640
				self.editor(function(oEditor) {
641
					oEditor.setPlain(sResult);
642
				});
643
			},
644
			this.oEditor.getData(false, true),
645
			this.currentIdentity(),
646
			this.to(),
647
			this.cc(),
648
			this.bcc()
649
		]);
650
	}
651
};
652
653
ComposePopupView.prototype.reloadDraftFolder = function()
654
{
655
	var
656
		sDraftFolder = FolderStore.draftFolder();
657
658
	if ('' !== sDraftFolder && Consts.UNUSED_OPTION_VALUE !== sDraftFolder)
659
	{
660
		Cache.setFolderHash(sDraftFolder, '');
661
		if (FolderStore.currentFolderFullNameRaw() === sDraftFolder)
662
		{
663
			require('App/User').default.reloadMessageList(true);
664
		}
665
		else
666
		{
667
			require('App/User').default.folderInformation(sDraftFolder);
668
		}
669
	}
670
};
671
672
ComposePopupView.prototype.findIdentityByMessage = function(sComposeType, oMessage)
673
{
674
	var
675
		aIdentities = IdentityStore.identities(),
676
		iResultIndex = 1000,
677
		oResultIdentity = null,
678
		oIdentitiesCache = {},
679
680
		fEachHelper = function(oItem) {
681
682
			if (oItem && oItem.email && oIdentitiesCache[oItem.email])
683
			{
684
				if (!oResultIdentity || iResultIndex > oIdentitiesCache[oItem.email][1])
685
				{
686
					oResultIdentity = oIdentitiesCache[oItem.email][0];
687
					iResultIndex = oIdentitiesCache[oItem.email][1];
688
				}
689
			}
690
		};
691
692
	_.each(aIdentities, function(oItem, iIndex) {
693
		oIdentitiesCache[oItem.email()] = [oItem, iIndex];
694
	});
695
696
	if (oMessage)
697
	{
698
		switch (sComposeType)
699
		{
700
			case Enums.ComposeType.Empty:
701
				break;
702
			case Enums.ComposeType.Reply:
703
			case Enums.ComposeType.ReplyAll:
704
			case Enums.ComposeType.Forward:
705
			case Enums.ComposeType.ForwardAsAttachment:
706
				_.each(_.union(oMessage.to, oMessage.cc, oMessage.bcc), fEachHelper);
707
				if (!oResultIdentity) {
708
					_.each(oMessage.deliveredTo, fEachHelper);
709
				}
710
				break;
711
			case Enums.ComposeType.Draft:
712
				_.each(_.union(oMessage.from, oMessage.replyTo), fEachHelper);
713
				break;
714
			// no default
715
		}
716
	}
717
718
	return oResultIdentity || aIdentities[0] || null;
719
};
720
721
ComposePopupView.prototype.selectIdentity = function(oIdentity)
722
{
723
	if (oIdentity && oIdentity.item)
724
	{
725
		this.currentIdentity(oIdentity.item);
726
		this.setSignatureFromIdentity(oIdentity.item);
727
	}
728
};
729
730
ComposePopupView.prototype.sendMessageResponse = function(sResult, oData)
731
{
732
	var
733
		bResult = false,
734
		sMessage = '';
735
736
	this.sending(false);
737
738
	if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
739
	{
740
		bResult = true;
741
		if (this.modalVisibility())
742
		{
743
			Utils.delegateRun(this, 'closeCommand');
744
		}
745
	}
746
747
	if (this.modalVisibility() && !bResult)
748
	{
749
		if (oData && Enums.Notification.CantSaveMessage === oData.ErrorCode)
750
		{
751
			this.sendSuccessButSaveError(true);
752
			this.savedErrorDesc(Utils.trim(Translator.i18n('COMPOSE/SAVED_ERROR_ON_SEND')));
753
		}
754
		else
755
		{
756
			sMessage = Translator.getNotification(oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantSendMessage,
757
				oData && oData.ErrorMessage ? oData.ErrorMessage : '');
758
759
			this.sendError(true);
760
			this.sendErrorDesc(sMessage || Translator.getNotification(Enums.Notification.CantSendMessage));
761
		}
762
	}
763
764
	this.reloadDraftFolder();
765
};
766
767
ComposePopupView.prototype.saveMessageResponse = function(sResult, oData)
768
{
769
	var bResult = false;
770
771
	this.saving(false);
772
773
	if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
774
	{
775
		if (oData.Result.NewFolder && oData.Result.NewUid)
776
		{
777
			bResult = true;
778
779
			if (this.bFromDraft)
780
			{
781
				var oMessage = MessageStore.message();
782
				if (oMessage && this.draftFolder() === oMessage.folderFullNameRaw && this.draftUid() === oMessage.uid)
783
				{
784
					MessageStore.message(null);
785
				}
786
			}
787
788
			this.draftFolder(oData.Result.NewFolder);
789
			this.draftUid(oData.Result.NewUid);
790
791
			this.savedTime(window.Math.round((new window.Date()).getTime() / 1000));
792
793
			if (this.bFromDraft)
794
			{
795
				Cache.setFolderHash(this.draftFolder(), '');
796
			}
797
		}
798
	}
799
800
	if (!bResult)
801
	{
802
		this.savedError(true);
803
		this.savedErrorDesc(Translator.getNotification(Enums.Notification.CantSaveMessage));
804
	}
805
806
	this.reloadDraftFolder();
807
};
808
809
ComposePopupView.prototype.onHide = function()
810
{
811
	this.autosaveStop();
812
813
	if (!this.bSkipNextHide)
814
	{
815
		AppStore.composeInEdit(false);
816
		this.reset();
817
	}
818
819
	this.bSkipNextHide = false;
820
821
	this.to.focused(false);
822
823
	kn.routeOn();
824
};
825
826
ComposePopupView.prototype.editor = function(fOnInit)
827
{
828
	if (fOnInit)
829
	{
830
		var self = this;
831
		if (!this.oEditor && this.composeEditorArea())
832
		{
833
// _.delay(function() {
834
			self.oEditor = new HtmlEditor(self.composeEditorArea(), null, function() {
835
				fOnInit(self.oEditor);
836
				self.resizerTrigger();
837
			}, function(bHtml) {
838
				self.isHtml(!!bHtml);
839
			});
840
// }, 1000);
841
		}
842
		else if (this.oEditor)
843
		{
844
			fOnInit(this.oEditor);
845
			this.resizerTrigger();
846
		}
847
	}
848
};
849
850
ComposePopupView.prototype.converSignature = function(sSignature)
851
{
852
	var
853
		iLimit = 10,
854
		aMoments = [],
855
		oMomentRegx = /{{MOMENT:([^}]+)}}/g,
856
		sFrom = '';
857
858
	sSignature = sSignature.replace(/[\r]/g, '');
859
860
	sFrom = this.oLastMessage ? this.emailArrayToStringLineHelper(this.oLastMessage.from, true) : '';
861
	if ('' !== sFrom)
862
	{
863
		sSignature = sSignature.replace(/{{FROM-FULL}}/g, sFrom);
864
865
		if (-1 === sFrom.indexOf(' ') && 0 < sFrom.indexOf('@'))
866
		{
867
			sFrom = sFrom.replace(/@[\S]+/, '');
868
		}
869
870
		sSignature = sSignature.replace(/{{FROM}}/g, sFrom);
871
	}
872
873
	sSignature = sSignature.replace(/[\s]{1,2}{{FROM}}/g, '{{FROM}}');
874
	sSignature = sSignature.replace(/[\s]{1,2}{{FROM-FULL}}/g, '{{FROM-FULL}}');
875
876
	sSignature = sSignature.replace(/{{FROM}}/g, '');
877
	sSignature = sSignature.replace(/{{FROM-FULL}}/g, '');
878
879
	if (-1 < sSignature.indexOf('{{DATE}}'))
880
	{
881
		sSignature = sSignature.replace(/{{DATE}}/g, Momentor.format(0, 'llll'));
882
	}
883
884
	if (-1 < sSignature.indexOf('{{TIME}}'))
885
	{
886
		sSignature = sSignature.replace(/{{TIME}}/g, Momentor.format(0, 'LT'));
887
	}
888
	if (-1 < sSignature.indexOf('{{MOMENT:'))
889
	{
890
		try
891
		{
892
			var oMatch = null;
0 ignored issues
show
Unused Code introduced by
The assignment to oMatch seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
893
			while (null !== (oMatch = oMomentRegx.exec(sSignature))) // eslint-disable-line no-cond-assign
894
			{
895
				if (oMatch && oMatch[0] && oMatch[1])
896
				{
897
					aMoments.push([oMatch[0], oMatch[1]]);
898
				}
899
900
				iLimit -= 1;
901
				if (0 === iLimit)
902
				{
903
					break;
904
				}
905
			}
906
907
			if (aMoments && 0 < aMoments.length)
908
			{
909
				_.each(aMoments, function(aData) {
910
					sSignature = sSignature.replace(
911
						aData[0], Momentor.format(0, aData[1]));
912
				});
913
			}
914
915
			sSignature = sSignature.replace(/{{MOMENT:[^}]+}}/g, '');
916
		}
917
		catch (e) {} // eslint-disable-line no-empty
1 ignored issue
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
918
	}
919
920
	return sSignature;
921
};
922
923
ComposePopupView.prototype.setSignatureFromIdentity = function(oIdentity)
924
{
925
	if (oIdentity)
926
	{
927
		var self = this;
928
		this.editor(function(oEditor) {
929
			var
930
				bHtml = false,
931
				sSignature = oIdentity.signature();
932
933
			if ('' !== sSignature)
934
			{
935
				if (':HTML:' === sSignature.substr(0, 6))
936
				{
937
					bHtml = true;
938
					sSignature = sSignature.substr(6);
939
				}
940
			}
941
942
			oEditor.setSignature(self.converSignature(sSignature),
943
				bHtml, !!oIdentity.signatureInsertBefore());
944
		});
945
	}
946
};
947
948
/**
949
 * @param {string=} sType = Enums.ComposeType.Empty
950
 * @param {?MessageModel|Array=} oMessageOrArray = null
951
 * @param {Array=} aToEmails = null
952
 * @param {Array=} aCcEmails = null
953
 * @param {Array=} aBccEmails = null
954
 * @param {string=} sCustomSubject = null
955
 * @param {string=} sCustomPlainText = null
956
 */
957
ComposePopupView.prototype.onShow = function(sType, oMessageOrArray,
958
	aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText)
959
{
960
	kn.routeOff();
961
962
	this.autosaveStart();
963
964
	if (AppStore.composeInEdit())
965
	{
966
		sType = sType || Enums.ComposeType.Empty;
967
968
		var self = this;
969
970
		if (Enums.ComposeType.Empty !== sType)
971
		{
972
			kn.showScreenPopup(require('View/Popup/Ask'), [Translator.i18n('COMPOSE/DISCARD_UNSAVED_DATA'), function() {
973
				self.initOnShow(sType, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText);
974
			}, null, null, null, false]);
975
		}
976
		else
977
		{
978
			this.addEmailsTo(this.to, aToEmails);
979
			this.addEmailsTo(this.cc, aCcEmails);
980
			this.addEmailsTo(this.bcc, aBccEmails);
981
982
			if (Utils.isNormal(sCustomSubject) && '' !== sCustomSubject &&
983
				'' === this.subject())
984
			{
985
				this.subject(sCustomSubject);
986
			}
987
		}
988
	}
989
	else
990
	{
991
		this.initOnShow(sType, oMessageOrArray, aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText);
992
	}
993
};
994
995
/**
996
 * @param {Function} fKoValue
997
 * @param {Array} aEmails
998
 */
999
ComposePopupView.prototype.addEmailsTo = function(fKoValue, aEmails)
1000
{
1001
	var
1002
		sValue = Utils.trim(fKoValue()),
1003
		aValue = [];
0 ignored issues
show
Unused Code introduced by
The assignment to variable aValue seems to be never used. Consider removing it.
Loading history...
1004
1005
	if (Utils.isNonEmptyArray(aEmails))
1006
	{
1007
		aValue = _.uniq(_.compact(_.map(aEmails, function(oItem) {
1008
			return oItem ? oItem.toLine(false) : null;
1009
		})));
1010
1011
		fKoValue(sValue + ('' === sValue ? '' : ', ') + Utils.trim(aValue.join(', ')));
1012
	}
1013
};
1014
1015
/**
1016
 *
1017
 * @param {Array} aList
1018
 * @param {boolean} bFriendly
1019
 * @returns {string}
1020
 */
1021
ComposePopupView.prototype.emailArrayToStringLineHelper = function(aList, bFriendly)
1022
{
1023
	var
1024
		iIndex = 0,
1025
		iLen = aList.length,
1026
		aResult = [];
1027
1028
	for (; iIndex < iLen; iIndex++)
1029
	{
1030
		aResult.push(aList[iIndex].toLine(!!bFriendly));
1031
	}
1032
1033
	return aResult.join(', ');
1034
};
1035
1036
/**
1037
 * @param {string=} sType = Enums.ComposeType.Empty
1038
 * @param {?MessageModel|Array=} oMessageOrArray = null
1039
 * @param {Array=} aToEmails = null
1040
 * @param {Array=} aCcEmails = null
1041
 * @param {Array=} aBccEmails = null
1042
 * @param {string=} sCustomSubject = null
1043
 * @param {string=} sCustomPlainText = null
1044
 */
1045
ComposePopupView.prototype.initOnShow = function(sType, oMessageOrArray,
1046
	aToEmails, aCcEmails, aBccEmails, sCustomSubject, sCustomPlainText)
1047
{
1048
	AppStore.composeInEdit(true);
1049
1050
	var
1051
		self = this,
1052
		sFrom = '',
1053
		sTo = '',
1054
		sCc = '',
1055
		sDate = '',
1056
		sSubject = '',
1057
		sText = '',
1058
		sReplyTitle = '',
1059
		oExcludeEmail = {},
1060
		oIdentity = null,
1061
		mEmail = AccountStore.email(),
1062
		aDraftInfo = null,
1063
		oMessage = null,
1064
		sComposeType = sType || Enums.ComposeType.Empty;
1065
1066
	oMessageOrArray = oMessageOrArray || null;
1067
	if (oMessageOrArray && Utils.isNormal(oMessageOrArray))
1068
	{
1069
		oMessage = Utils.isArray(oMessageOrArray) && 1 === oMessageOrArray.length ? oMessageOrArray[0] :
1070
			(!Utils.isArray(oMessageOrArray) ? oMessageOrArray : null);
1071
	}
1072
1073
	this.oLastMessage = oMessage;
1074
1075
	if (null !== mEmail)
1076
	{
1077
		oExcludeEmail[mEmail] = true;
1078
	}
1079
1080
	this.reset();
1081
1082
	oIdentity = this.findIdentityByMessage(sComposeType, oMessage);
1083
	if (oIdentity)
1084
	{
1085
		oExcludeEmail[oIdentity.email()] = true;
1086
	}
1087
1088
	if (Utils.isNonEmptyArray(aToEmails))
1089
	{
1090
		this.to(this.emailArrayToStringLineHelper(aToEmails));
1091
	}
1092
1093
	if (Utils.isNonEmptyArray(aCcEmails))
1094
	{
1095
		this.cc(this.emailArrayToStringLineHelper(aCcEmails));
1096
	}
1097
1098
	if (Utils.isNonEmptyArray(aBccEmails))
1099
	{
1100
		this.bcc(this.emailArrayToStringLineHelper(aBccEmails));
1101
	}
1102
1103
	if ('' !== sComposeType && oMessage)
1104
	{
1105
		sDate = Momentor.format(oMessage.dateTimeStampInUTC(), 'FULL');
1106
		sSubject = oMessage.subject();
1107
		aDraftInfo = oMessage.aDraftInfo;
1108
1109
		var oText = $(oMessage.body).clone();
1110
		if (oText)
1111
		{
1112
			Utils.clearBqSwitcher(oText);
1113
1114
			sText = oText.html();
1115
		}
1116
1117
		switch (sComposeType)
1118
		{
1119
			case Enums.ComposeType.Empty:
1120
				break;
1121
1122
			case Enums.ComposeType.Reply:
1123
				this.to(this.emailArrayToStringLineHelper(oMessage.replyEmails(oExcludeEmail)));
1124
				this.subject(Utils.replySubjectAdd('Re', sSubject));
1125
				this.prepearMessageAttachments(oMessage, sComposeType);
1126
				this.aDraftInfo = ['reply', oMessage.uid, oMessage.folderFullNameRaw];
1127
				this.sInReplyTo = oMessage.sMessageId;
1128
				this.sReferences = Utils.trim(this.sInReplyTo + ' ' + oMessage.sReferences);
1129
				break;
1130
1131
			case Enums.ComposeType.ReplyAll:
1132
				var aResplyAllParts = oMessage.replyAllEmails(oExcludeEmail);
1133
				this.to(this.emailArrayToStringLineHelper(aResplyAllParts[0]));
1134
				this.cc(this.emailArrayToStringLineHelper(aResplyAllParts[1]));
1135
				this.subject(Utils.replySubjectAdd('Re', sSubject));
1136
				this.prepearMessageAttachments(oMessage, sComposeType);
1137
				this.aDraftInfo = ['reply', oMessage.uid, oMessage.folderFullNameRaw];
1138
				this.sInReplyTo = oMessage.sMessageId;
1139
				this.sReferences = Utils.trim(this.sInReplyTo + ' ' + oMessage.references());
1140
				break;
1141
1142
			case Enums.ComposeType.Forward:
1143
				this.subject(Utils.replySubjectAdd('Fwd', sSubject));
1144
				this.prepearMessageAttachments(oMessage, sComposeType);
1145
				this.aDraftInfo = ['forward', oMessage.uid, oMessage.folderFullNameRaw];
1146
				this.sInReplyTo = oMessage.sMessageId;
1147
				this.sReferences = Utils.trim(this.sInReplyTo + ' ' + oMessage.sReferences);
1148
				break;
1149
1150
			case Enums.ComposeType.ForwardAsAttachment:
1151
				this.subject(Utils.replySubjectAdd('Fwd', sSubject));
1152
				this.prepearMessageAttachments(oMessage, sComposeType);
1153
				this.aDraftInfo = ['forward', oMessage.uid, oMessage.folderFullNameRaw];
1154
				this.sInReplyTo = oMessage.sMessageId;
1155
				this.sReferences = Utils.trim(this.sInReplyTo + ' ' + oMessage.sReferences);
1156
				break;
1157
1158
			case Enums.ComposeType.Draft:
1159
				this.to(this.emailArrayToStringLineHelper(oMessage.to));
1160
				this.cc(this.emailArrayToStringLineHelper(oMessage.cc));
1161
				this.bcc(this.emailArrayToStringLineHelper(oMessage.bcc));
1162
				this.replyTo(this.emailArrayToStringLineHelper(oMessage.replyTo));
1163
1164
				this.bFromDraft = true;
1165
1166
				this.draftFolder(oMessage.folderFullNameRaw);
1167
				this.draftUid(oMessage.uid);
1168
1169
				this.subject(sSubject);
1170
				this.prepearMessageAttachments(oMessage, sComposeType);
1171
1172
				this.aDraftInfo = Utils.isNonEmptyArray(aDraftInfo) && 3 === aDraftInfo.length ? aDraftInfo : null;
1173
				this.sInReplyTo = oMessage.sInReplyTo;
1174
				this.sReferences = oMessage.sReferences;
1175
				break;
1176
1177
			case Enums.ComposeType.EditAsNew:
1178
				this.to(this.emailArrayToStringLineHelper(oMessage.to));
1179
				this.cc(this.emailArrayToStringLineHelper(oMessage.cc));
1180
				this.bcc(this.emailArrayToStringLineHelper(oMessage.bcc));
1181
				this.replyTo(this.emailArrayToStringLineHelper(oMessage.replyTo));
1182
1183
				this.subject(sSubject);
1184
				this.prepearMessageAttachments(oMessage, sComposeType);
1185
1186
				this.aDraftInfo = Utils.isNonEmptyArray(aDraftInfo) && 3 === aDraftInfo.length ? aDraftInfo : null;
1187
				this.sInReplyTo = oMessage.sInReplyTo;
1188
				this.sReferences = oMessage.sReferences;
1189
				break;
1190
			// no default
1191
		}
1192
1193
		switch (sComposeType)
1194
		{
1195
			case Enums.ComposeType.Reply:
1196
			case Enums.ComposeType.ReplyAll:
1197
				sFrom = oMessage.fromToLine(false, true);
1198
				sReplyTitle = Translator.i18n('COMPOSE/REPLY_MESSAGE_TITLE', {
1199
					'DATETIME': sDate,
1200
					'EMAIL': sFrom
1201
				});
1202
1203
				sText = '<br /><br />' + sReplyTitle + ':' +
1204
					'<blockquote>' + Utils.trim(sText) + '</blockquote>';
1205
//						'<blockquote><p>' + Utils.trim(sText) + '</p></blockquote>';
1206
1207
				break;
1208
1209
			case Enums.ComposeType.Forward:
1210
				sFrom = oMessage.fromToLine(false, true);
1211
				sTo = oMessage.toToLine(false, true);
1212
				sCc = oMessage.ccToLine(false, true);
1213
				sText = '<br /><br />' + Translator.i18n('COMPOSE/FORWARD_MESSAGE_TOP_TITLE') +
1214
						'<br />' + Translator.i18n('COMPOSE/FORWARD_MESSAGE_TOP_FROM') + ': ' + sFrom +
1215
						'<br />' + Translator.i18n('COMPOSE/FORWARD_MESSAGE_TOP_TO') + ': ' + sTo +
1216
						(0 < sCc.length ? '<br />' + Translator.i18n('COMPOSE/FORWARD_MESSAGE_TOP_CC') + ': ' + sCc : '') +
1217
						'<br />' + Translator.i18n('COMPOSE/FORWARD_MESSAGE_TOP_SENT') + ': ' + Utils.encodeHtml(sDate) +
1218
						'<br />' + Translator.i18n('COMPOSE/FORWARD_MESSAGE_TOP_SUBJECT') + ': ' + Utils.encodeHtml(sSubject) +
1219
						'<br /><br />' + Utils.trim(sText) + '<br /><br />';
1220
				break;
1221
1222
			case Enums.ComposeType.ForwardAsAttachment:
1223
				sText = '';
1224
				break;
1225
			// no default
1226
		}
1227
1228
		this.editor(function(oEditor) {
1229
1230
			oEditor.setHtml(sText, false);
1231
1232
			if (Enums.EditorDefaultType.PlainForced === self.editorDefaultType() ||
1233
				(!oMessage.isHtml() && Enums.EditorDefaultType.HtmlForced !== self.editorDefaultType()))
1234
			{
1235
				oEditor.modeToggle(false);
1236
			}
1237
1238
			if (oIdentity && Enums.ComposeType.Draft !== sComposeType && Enums.ComposeType.EditAsNew !== sComposeType)
1239
			{
1240
				self.setSignatureFromIdentity(oIdentity);
1241
			}
1242
1243
			self.setFocusInPopup();
1244
		});
1245
	}
1246
	else if (Enums.ComposeType.Empty === sComposeType)
1247
	{
1248
		this.subject(Utils.isNormal(sCustomSubject) ? '' + sCustomSubject : '');
1249
1250
		sText = Utils.isNormal(sCustomPlainText) ? '' + sCustomPlainText : '';
1251
1252
		this.editor(function(oEditor) {
1253
1254
			oEditor.setHtml(sText, false);
1255
1256
			if (Enums.EditorDefaultType.Html !== self.editorDefaultType() &&
1257
				Enums.EditorDefaultType.HtmlForced !== self.editorDefaultType())
1258
			{
1259
				oEditor.modeToggle(false);
1260
			}
1261
1262
			if (oIdentity)
1263
			{
1264
				self.setSignatureFromIdentity(oIdentity);
1265
			}
1266
1267
			self.setFocusInPopup();
1268
		});
1269
	}
1270
	else if (Utils.isNonEmptyArray(oMessageOrArray))
1271
	{
1272
		_.each(oMessageOrArray, function(oItem) {
1273
			self.addMessageAsAttachment(oItem);
1274
		});
1275
1276
		this.editor(function(oEditor) {
1277
1278
			oEditor.setHtml('', false);
1279
1280
			if (Enums.EditorDefaultType.Html !== self.editorDefaultType() &&
1281
				Enums.EditorDefaultType.HtmlForced !== self.editorDefaultType())
1282
			{
1283
				oEditor.modeToggle(false);
1284
			}
1285
1286
			if (oIdentity && Enums.ComposeType.Draft !== sComposeType && Enums.ComposeType.EditAsNew !== sComposeType)
1287
			{
1288
				self.setSignatureFromIdentity(oIdentity);
1289
			}
1290
1291
			self.setFocusInPopup();
1292
		});
1293
	}
1294
	else
1295
	{
1296
		this.setFocusInPopup();
1297
	}
1298
1299
	var downloads = this.getAttachmentsDownloadsForUpload();
1300
	if (Utils.isNonEmptyArray(downloads))
1301
	{
1302
		Remote.messageUploadAttachments(this.onMessageUploadAttachments, downloads);
1303
	}
1304
1305
	if (oIdentity)
1306
	{
1307
		this.currentIdentity(oIdentity);
1308
	}
1309
1310
	this.resizerTrigger();
1311
};
1312
1313
ComposePopupView.prototype.onMessageUploadAttachments = function(sResult, oData)
1314
{
1315
	if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
1316
	{
1317
		var self = this;
1318
		if (!this.viewModelVisibility())
1319
		{
1320
			_.each(oData.Result, function(id, tempName) {
1321
				var attachment = self.getAttachmentById(id);
1322
				if (attachment)
1323
				{
1324
					attachment.tempName(tempName);
1325
					attachment.waiting(false).uploading(false).complete(true);
1326
				}
1327
			});
1328
		}
1329
	}
1330
	else
1331
	{
1332
		this.setMessageAttachmentFailedDownloadText();
1333
	}
1334
};
1335
1336
ComposePopupView.prototype.setFocusInPopup = function()
1337
{
1338
	if (!Globals.bMobileDevice)
1339
	{
1340
		var self = this;
1341
		_.delay(function() {
1342
1343
			if ('' === self.to())
1344
			{
1345
				self.to.focused(true);
1346
			}
1347
			else if (self.oEditor)
1348
			{
1349
				if (!self.to.focused())
1350
				{
1351
					self.oEditor.focus();
1352
				}
1353
			}
1354
1355
		}, Enums.Magics.Time100ms);
1356
	}
1357
};
1358
1359
ComposePopupView.prototype.onShowWithDelay = function()
1360
{
1361
	this.resizerTrigger();
1362
};
1363
1364
ComposePopupView.prototype.tryToClosePopup = function()
1365
{
1366
	var
1367
		self = this,
1368
		PopupsAskViewModel = require('View/Popup/Ask');
1369
1370
	if (!kn.isPopupVisible(PopupsAskViewModel) && this.modalVisibility())
1371
	{
1372
		if (this.bSkipNextHide || (this.isEmptyForm() && !this.draftUid()))
1373
		{
1374
			Utils.delegateRun(self, 'closeCommand');
1375
		}
1376
		else
1377
		{
1378
			kn.showScreenPopup(PopupsAskViewModel, [Translator.i18n('POPUPS_ASK/DESC_WANT_CLOSE_THIS_WINDOW'), function() {
1379
				if (self.modalVisibility())
1380
				{
1381
					Utils.delegateRun(self, 'closeCommand');
1382
				}
1383
			}]);
1384
		}
1385
	}
1386
};
1387
1388
ComposePopupView.prototype.onBuild = function()
1389
{
1390
	this.initUploader();
1391
1392
	var
1393
		self = this,
1394
		oScript = null;
0 ignored issues
show
Unused Code introduced by
The assignment to oScript seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
1395
1396
	key('ctrl+q, command+q, ctrl+w, command+w', Enums.KeyState.Compose, function() {
1397
		return false;
1398
	});
1399
1400
	key('`', Enums.KeyState.Compose, function() {
1401
		if (self.oEditor && !self.oEditor.hasFocus() && !Utils.inFocus())
1402
		{
1403
			self.identitiesDropdownTrigger(true);
1404
			return false;
1405
		}
1406
1407
		return true;
1408
	});
1409
1410
	key('ctrl+`', Enums.KeyState.Compose, function() {
1411
		self.identitiesDropdownTrigger(true);
1412
		return false;
1413
	});
1414
1415
	key('esc, ctrl+down, command+down', Enums.KeyState.Compose, function() {
1416
		self.skipCommand();
1417
		return false;
1418
	});
1419
1420
	if (this.allowFolders)
1421
	{
1422
		key('ctrl+s, command+s', Enums.KeyState.Compose, function() {
1423
			self.saveCommand();
1424
			return false;
1425
		});
1426
	}
1427
1428
	if (Settings.appSettingsGet('allowCtrlEnterOnCompose'))
1429
	{
1430
		key('ctrl+enter, command+enter', Enums.KeyState.Compose, function() {
1431
			self.sendCommand();
1432
			return false;
1433
		});
1434
	}
1435
1436
	key('shift+esc', Enums.KeyState.Compose, function() {
1437
		if (self.modalVisibility())
1438
		{
1439
			self.tryToClosePopup();
1440
		}
1441
		return false;
1442
	});
1443
1444
	Events.sub('window.resize.real', this.resizerTrigger);
1445
	Events.sub('window.resize.real', _.debounce(this.resizerTrigger, Enums.Magics.Time50ms));
1446
1447
	if (this.dropboxEnabled() && this.dropboxApiKey() && !window.Dropbox)
1448
	{
1449
		oScript = window.document.createElement('script');
1450
		oScript.type = 'text/javascript';
1451
		oScript.src = 'https://www.dropbox.com/static/api/2/dropins.js';
1452
		$(oScript).attr('id', 'dropboxjs').attr('data-app-key', self.dropboxApiKey());
1453
1454
		window.document.body.appendChild(oScript);
1455
	}
1456
1457
	if (this.driveEnabled())
1458
	{
1459
		$.getScript('https://apis.google.com/js/api.js', function() {
1460
			if (window.gapi)
1461
			{
1462
				self.driveVisible(true);
1463
			}
1464
		});
1465
	}
1466
1467
	window.setInterval(function() {
1468
		if (self.modalVisibility() && self.oEditor)
1469
		{
1470
			self.oEditor.resize();
1471
		}
1472
	}, Enums.Magics.Time5s);
1473
};
1474
1475
ComposePopupView.prototype.driveCallback = function(sAccessToken, oData)
1476
{
1477
	if (oData && window.XMLHttpRequest && window.google &&
1478
		oData[window.google.picker.Response.ACTION] === window.google.picker.Action.PICKED &&
1479
		oData[window.google.picker.Response.DOCUMENTS] && oData[window.google.picker.Response.DOCUMENTS][0] &&
1480
		oData[window.google.picker.Response.DOCUMENTS][0].id)
1481
	{
1482
		var
1483
			self = this,
1484
			oRequest = new window.XMLHttpRequest();
1485
1486
		oRequest.open('GET', 'https://www.googleapis.com/drive/v2/files/' + oData[window.google.picker.Response.DOCUMENTS][0].id);
1487
		oRequest.setRequestHeader('Authorization', 'Bearer ' + sAccessToken);
1488
		oRequest.addEventListener('load', function() {
1489
			if (oRequest && oRequest.responseText)
1490
			{
1491
				var
1492
					oResponse = JSON.parse(oRequest.responseText),
1493
					fExport = function(oItem, sMimeType, sExt) {
1494
						if (oItem && oItem.exportLinks)
1495
						{
1496
							if (oItem.exportLinks[sMimeType])
1497
							{
1498
								oResponse.downloadUrl = oItem.exportLinks[sMimeType];
1499
								oResponse.title = oItem.title + '.' + sExt;
1500
								oResponse.mimeType = sMimeType;
1501
							}
1502
							else if (oItem.exportLinks['application/pdf'])
1503
							{
1504
								oResponse.downloadUrl = oItem.exportLinks['application/pdf'];
1505
								oResponse.title = oItem.title + '.pdf';
1506
								oResponse.mimeType = 'application/pdf';
1507
							}
1508
						}
1509
					};
1510
1511
				if (oResponse && !oResponse.downloadUrl && oResponse.mimeType && oResponse.exportLinks)
1512
				{
1513
					switch (oResponse.mimeType.toString().toLowerCase())
1514
					{
1515
						case 'application/vnd.google-apps.document':
1516
							fExport(oResponse, 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'docx');
1517
							break;
1518
						case 'application/vnd.google-apps.spreadsheet':
1519
							fExport(oResponse, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlsx');
1520
							break;
1521
						case 'application/vnd.google-apps.drawing':
1522
							fExport(oResponse, 'image/png', 'png');
1523
							break;
1524
						case 'application/vnd.google-apps.presentation':
1525
							fExport(oResponse, 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'pptx');
1526
							break;
1527
						default:
1528
							fExport(oResponse, 'application/pdf', 'pdf');
1529
							break;
1530
					}
1531
				}
1532
1533
				if (oResponse && oResponse.downloadUrl)
1534
				{
1535
					self.addDriveAttachment(oResponse, sAccessToken);
1536
				}
1537
			}
1538
		});
1539
1540
		oRequest.send();
1541
	}
1542
};
1543
1544
ComposePopupView.prototype.driveCreatePiker = function(oOauthToken)
1545
{
1546
	if (window.gapi && oOauthToken && oOauthToken.access_token)
1547
	{
1548
		var self = this;
1549
1550
		window.gapi.load('picker', {'callback': function() {
1551
1552
			if (window.google && window.google.picker)
1553
			{
1554
				var drivePicker = new window.google.picker.PickerBuilder()
1555
					// .addView(window.google.picker.ViewId.FOLDERS)
1556
					.addView(window.google.picker.ViewId.DOCS)
1557
					.setAppId(Settings.settingsGet('GoogleClientID'))
1558
					.setOAuthToken(oOauthToken.access_token)
1559
					.setCallback(_.bind(self.driveCallback, self, oOauthToken.access_token))
1560
					.enableFeature(window.google.picker.Feature.NAV_HIDDEN)
1561
					// .setOrigin(window.location.protocol + '//' + window.location.host)
1562
					.build();
1563
1564
				drivePicker.setVisible(true);
1565
			}
1566
		}});
1567
	}
1568
};
1569
1570
ComposePopupView.prototype.driveOpenPopup = function()
1571
{
1572
	if (window.gapi)
1573
	{
1574
		var self = this;
1575
1576
		window.gapi.load('auth', {'callback': function() {
1577
1578
			var
1579
				oAuthToken = window.gapi.auth.getToken(),
1580
				fResult = function(oAuthResult) {
1581
					if (oAuthResult && !oAuthResult.error)
1582
					{
1583
						var oToken = window.gapi.auth.getToken();
1584
						if (oToken)
1585
						{
1586
							self.driveCreatePiker(oToken);
1587
						}
1588
1589
						return true;
1590
					}
1591
1592
					return false;
1593
				};
1594
1595
			if (!oAuthToken)
1596
			{
1597
				window.gapi.auth.authorize({
1598
					'client_id': Settings.settingsGet('GoogleClientID'),
1599
					'scope': 'https://www.googleapis.com/auth/drive.readonly',
1600
					'immediate': true
1601
				}, function(oAuthResult) {
1602
1603
					if (!fResult(oAuthResult))
1604
					{
1605
						window.gapi.auth.authorize({
1606
							'client_id': Settings.settingsGet('GoogleClientID'),
1607
							'scope': 'https://www.googleapis.com/auth/drive.readonly',
1608
							'immediate': false
1609
						}, fResult);
1610
					}
1611
				});
1612
			}
1613
			else
1614
			{
1615
				self.driveCreatePiker(oAuthToken);
1616
			}
1617
		}});
1618
	}
1619
};
1620
1621
/**
1622
 * @param {string} sId
1623
 * @returns {?Object}
1624
 */
1625
ComposePopupView.prototype.getAttachmentById = function(sId)
1626
{
1627
	var
1628
		aAttachments = this.attachments(),
1629
		iIndex = 0,
1630
		iLen = aAttachments.length;
1631
1632
	for (; iIndex < iLen; iIndex++)
1633
	{
1634
		if (aAttachments[iIndex] && sId === aAttachments[iIndex].id)
1635
		{
1636
			return aAttachments[iIndex];
1637
		}
1638
	}
1639
1640
	return null;
1641
};
1642
1643
ComposePopupView.prototype.cancelAttachmentHelper = function(sId, oJua) {
1644
1645
	var self = this;
1646
	return function() {
1647
1648
		var attachment = _.find(self.attachments(), function(oItem) {
1649
			return oItem && oItem.id === sId;
1650
		});
1651
1652
		if (attachment)
1653
		{
1654
			self.attachments.remove(attachment);
1655
			Utils.delegateRunOnDestroy(attachment);
1656
1657
			if (oJua)
1658
			{
1659
				oJua.cancel(sId);
1660
			}
1661
		}
1662
	};
1663
1664
};
1665
1666
ComposePopupView.prototype.initUploader = function()
1667
{
1668
	if (this.composeUploaderButton())
1669
	{
1670
		var
1671
			oUploadCache = {},
1672
			iAttachmentSizeLimit = Utils.pInt(Settings.settingsGet('AttachmentLimit')),
1673
			oJua = new Jua({
1674
				'action': Links.upload(),
1675
				'name': 'uploader',
1676
				'queueSize': 2,
1677
				'multipleSizeLimit': 50,
1678
				'clickElement': this.composeUploaderButton(),
1679
				'dragAndDropElement': this.composeUploaderDropPlace()
1680
			});
1681
1682
		if (oJua)
1683
		{
1684
			oJua
1685
//				.on('onLimitReached', function(iLimit) {
1686
//					alert(iLimit);
1687
//				})
1688
				.on('onDragEnter', _.bind(function() {
1689
					this.dragAndDropOver(true);
1690
				}, this))
1691
				.on('onDragLeave', _.bind(function() {
1692
					this.dragAndDropOver(false);
1693
				}, this))
1694
				.on('onBodyDragEnter', _.bind(function() {
1695
					this.attachmentsPlace(true);
1696
					this.dragAndDropVisible(true);
1697
				}, this))
1698
				.on('onBodyDragLeave', _.bind(function() {
1699
					this.dragAndDropVisible(false);
1700
				}, this))
1701
				.on('onProgress', _.bind(function(sId, iLoaded, iTotal) {
1702
					var oItem = null;
0 ignored issues
show
Unused Code introduced by
The assignment to oItem seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
1703
					if (Utils.isUnd(oUploadCache[sId]))
1704
					{
1705
						oItem = this.getAttachmentById(sId);
1706
						if (oItem)
1707
						{
1708
							oUploadCache[sId] = oItem;
1709
						}
1710
					}
1711
					else
1712
					{
1713
						oItem = oUploadCache[sId];
1714
					}
1715
1716
					if (oItem)
1717
					{
1718
						oItem.progress(window.Math.floor(iLoaded / iTotal * 100));
1719
					}
1720
1721
				}, this))
1722
				.on('onSelect', _.bind(function(sId, oData) {
1723
1724
					this.dragAndDropOver(false);
1725
1726
					var
1727
						self = this,
1728
						sFileName = Utils.isUnd(oData.FileName) ? '' : oData.FileName.toString(),
1729
						mSize = Utils.isNormal(oData.Size) ? Utils.pInt(oData.Size) : null,
1730
						oAttachment = new ComposeAttachmentModel(sId, sFileName, mSize);
1731
1732
					oAttachment.cancel = self.cancelAttachmentHelper(sId, oJua);
1733
1734
					this.attachments.push(oAttachment);
1735
1736
					this.attachmentsPlace(true);
1737
1738
					if (0 < mSize && 0 < iAttachmentSizeLimit && iAttachmentSizeLimit < mSize)
1739
					{
1740
						oAttachment
1741
							.waiting(false).uploading(true).complete(true)
1742
							.error(Translator.i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG'));
1743
1744
						return false;
1745
					}
1746
1747
					return true;
1748
1749
				}, this))
1750
				.on('onStart', _.bind(function(sId) {
1751
1752
					var
1753
						oItem = null;
0 ignored issues
show
Unused Code introduced by
The assignment to oItem seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
1754
1755
					if (Utils.isUnd(oUploadCache[sId]))
1756
					{
1757
						oItem = this.getAttachmentById(sId);
1758
						if (oItem)
1759
						{
1760
							oUploadCache[sId] = oItem;
1761
						}
1762
					}
1763
					else
1764
					{
1765
						oItem = oUploadCache[sId];
1766
					}
1767
1768
					if (oItem)
1769
					{
1770
						oItem.waiting(false).uploading(true).complete(false);
1771
					}
1772
1773
				}, this))
1774
				.on('onComplete', _.bind(function(sId, bResult, oData) {
1775
1776
					var
1777
						sError = '',
1778
						mErrorCode = null,
0 ignored issues
show
Unused Code introduced by
The assignment to mErrorCode seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
1779
						oAttachmentJson = null,
0 ignored issues
show
Unused Code introduced by
The assignment to oAttachmentJson seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
1780
						oAttachment = this.getAttachmentById(sId);
1781
1782
					oAttachmentJson = bResult && oData && oData.Result && oData.Result.Attachment ? oData.Result.Attachment : null;
1783
					mErrorCode = oData && oData.Result && oData.Result.ErrorCode ? oData.Result.ErrorCode : null;
1784
1785
					if (null !== mErrorCode)
1786
					{
1787
						sError = Translator.getUploadErrorDescByCode(mErrorCode);
1788
					}
1789
					else if (!oAttachmentJson)
1790
					{
1791
						sError = Translator.i18n('UPLOAD/ERROR_UNKNOWN');
1792
					}
1793
1794
					if (oAttachment)
1795
					{
1796
						if ('' !== sError && 0 < sError.length)
1797
						{
1798
							oAttachment
1799
								.waiting(false)
1800
								.uploading(false)
1801
								.complete(true)
1802
								.error(sError);
1803
						}
1804
						else if (oAttachmentJson)
1805
						{
1806
							oAttachment
1807
								.waiting(false)
1808
								.uploading(false)
1809
								.complete(true);
1810
1811
							oAttachment.initByUploadJson(oAttachmentJson);
1812
						}
1813
1814
						if (Utils.isUnd(oUploadCache[sId]))
1815
						{
1816
							delete (oUploadCache[sId]);
1817
						}
1818
					}
1819
1820
				}, this));
1821
1822
			this
1823
				.addAttachmentEnabled(true)
1824
				.dragAndDropEnabled(oJua.isDragAndDropSupported());
1825
		}
1826
		else
1827
		{
1828
			this
1829
				.addAttachmentEnabled(false)
1830
				.dragAndDropEnabled(false);
1831
		}
1832
	}
1833
};
1834
1835
/**
1836
 * @returns {Object}
1837
 */
1838
ComposePopupView.prototype.prepearAttachmentsForSendOrSave = function()
1839
{
1840
	var oResult = {};
1841
	_.each(this.attachmentsInReady(), function(oItem) {
1842
		if (oItem && '' !== oItem.tempName() && oItem.enabled())
1843
		{
1844
			oResult[oItem.tempName()] = [
1845
				oItem.fileName(),
1846
				oItem.isInline ? '1' : '0',
1847
				oItem.CID,
1848
				oItem.contentLocation
1849
			];
1850
		}
1851
	});
1852
1853
	return oResult;
1854
};
1855
1856
/**
1857
 * @param {MessageModel} oMessage
1858
 */
1859
ComposePopupView.prototype.addMessageAsAttachment = function(oMessage)
1860
{
1861
	if (oMessage)
1862
	{
1863
		var
1864
			oAttachment = null,
0 ignored issues
show
Unused Code introduced by
The assignment to oAttachment seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
1865
			sTemp = oMessage.subject();
1866
1867
		sTemp = '.eml' === sTemp.substr(-4).toLowerCase() ? sTemp : sTemp + '.eml';
1868
		oAttachment = new ComposeAttachmentModel(
1869
			oMessage.requestHash, sTemp, oMessage.size()
1870
		);
1871
1872
		oAttachment.fromMessage = true;
1873
		oAttachment.cancel = this.cancelAttachmentHelper(oMessage.requestHash);
1874
		oAttachment.waiting(false).uploading(true).complete(true);
1875
1876
		this.attachments.push(oAttachment);
1877
	}
1878
};
1879
1880
/**
1881
 * @param {Object} oDropboxFile
1882
 * @returns {boolean}
1883
 */
1884
ComposePopupView.prototype.addDropboxAttachment = function(oDropboxFile)
1885
{
1886
	var
1887
		oAttachment = null,
1888
		iAttachmentSizeLimit = Utils.pInt(Settings.settingsGet('AttachmentLimit')),
1889
		mSize = oDropboxFile.bytes;
1890
1891
	oAttachment = new ComposeAttachmentModel(
1892
		oDropboxFile.link, oDropboxFile.name, mSize
1893
	);
1894
1895
	oAttachment.fromMessage = false;
1896
	oAttachment.cancel = this.cancelAttachmentHelper(oDropboxFile.link);
1897 View Code Duplication
	oAttachment.waiting(false).uploading(true).complete(false);
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1898
1899
	this.attachments.push(oAttachment);
1900
1901
	this.attachmentsPlace(true);
1902
1903
	if (0 < mSize && 0 < iAttachmentSizeLimit && iAttachmentSizeLimit < mSize)
1904
	{
1905
		oAttachment.uploading(false).complete(true);
1906
		oAttachment.error(Translator.i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG'));
1907
		return false;
1908
	}
1909
1910
	Remote.composeUploadExternals(function(sResult, oData) {
1911
1912
		var bResult = false;
1913
		oAttachment.uploading(false).complete(true);
1914
1915
		if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
1916
		{
1917
			if (oData.Result[oAttachment.id])
1918
			{
1919
				bResult = true;
1920
				oAttachment.tempName(oData.Result[oAttachment.id]);
1921
			}
1922
		}
1923
1924
		if (!bResult)
1925
		{
1926
			oAttachment.error(Translator.getUploadErrorDescByCode(Enums.UploadErrorCode.FileNoUploaded));
1927
		}
1928
1929
	}, [oDropboxFile.link]);
1930
1931
	return true;
1932
};
1933
1934
/**
1935
 * @param {Object} oDriveFile
1936
 * @param {string} sAccessToken
1937
 * @returns {boolean}
1938
 */
1939
ComposePopupView.prototype.addDriveAttachment = function(oDriveFile, sAccessToken)
1940
{
1941
	var
1942
		iAttachmentSizeLimit = Utils.pInt(Settings.settingsGet('AttachmentLimit')),
1943
		oAttachment = null,
1944
		mSize = oDriveFile.fileSize ? Utils.pInt(oDriveFile.fileSize) : 0;
1945
1946
	oAttachment = new ComposeAttachmentModel(
1947
		oDriveFile.downloadUrl, oDriveFile.title, mSize
1948
	);
1949
1950
	oAttachment.fromMessage = false;
1951
	oAttachment.cancel = this.cancelAttachmentHelper(oDriveFile.downloadUrl);
1952 View Code Duplication
	oAttachment.waiting(false).uploading(true).complete(false);
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1953
1954
	this.attachments.push(oAttachment);
1955
1956
	this.attachmentsPlace(true);
1957
1958
	if (0 < mSize && 0 < iAttachmentSizeLimit && iAttachmentSizeLimit < mSize)
1959
	{
1960
		oAttachment.uploading(false).complete(true);
1961
		oAttachment.error(Translator.i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG'));
1962
		return false;
1963
	}
1964
1965
	Remote.composeUploadDrive(function(sResult, oData) {
1966
1967
		var bResult = false;
1968
		oAttachment.uploading(false).complete(true);
1969
1970
		if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
1971
		{
1972
			if (oData.Result[oAttachment.id])
1973
			{
1974
				bResult = true;
1975
				oAttachment.tempName(oData.Result[oAttachment.id][0]);
1976
				oAttachment.size(Utils.pInt(oData.Result[oAttachment.id][1]));
1977
			}
1978
		}
1979
1980
		if (!bResult)
1981
		{
1982
			oAttachment.error(Translator.getUploadErrorDescByCode(Enums.UploadErrorCode.FileNoUploaded));
1983
		}
1984
1985
	}, oDriveFile.downloadUrl, sAccessToken);
1986
1987
	return true;
1988
};
1989
1990
/**
1991
 * @param {MessageModel} oMessage
1992
 * @param {string} sType
1993
 */
1994
ComposePopupView.prototype.prepearMessageAttachments = function(oMessage, sType)
1995
{
1996
	if (oMessage)
1997
	{
1998
		var
1999
			aAttachments = Utils.isNonEmptyArray(oMessage.attachments()) ? oMessage.attachments() : [],
2000
			iIndex = 0,
2001
			iLen = aAttachments.length,
2002
			oAttachment = null,
0 ignored issues
show
Unused Code introduced by
The assignment to oAttachment seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
2003
			oItem = null,
0 ignored issues
show
Unused Code introduced by
The assignment to oItem seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
2004
			bAdd = false;
0 ignored issues
show
Unused Code introduced by
The assignment to variable bAdd seems to be never used. Consider removing it.
Loading history...
2005
2006
		if (Enums.ComposeType.ForwardAsAttachment === sType)
2007
		{
2008
			this.addMessageAsAttachment(oMessage);
2009
		}
2010
		else
2011
		{
2012
			for (; iIndex < iLen; iIndex++)
2013
			{
2014
				oItem = aAttachments[iIndex];
2015
2016
				bAdd = false;
2017
				switch (sType)
2018
				{
2019
					case Enums.ComposeType.Reply:
2020
					case Enums.ComposeType.ReplyAll:
2021
						bAdd = oItem.isLinked;
2022
						break;
2023
2024
					case Enums.ComposeType.Forward:
2025
					case Enums.ComposeType.Draft:
2026
					case Enums.ComposeType.EditAsNew:
2027
						bAdd = true;
2028
						break;
2029
					// no default
2030
				}
2031
2032
				if (bAdd)
2033
				{
2034
					oAttachment = new ComposeAttachmentModel(
2035
						oItem.download, oItem.fileName, oItem.estimatedSize,
2036
						oItem.isInline, oItem.isLinked, oItem.cid, oItem.contentLocation
2037
					);
2038
2039
					oAttachment.fromMessage = true;
2040
					oAttachment.cancel = this.cancelAttachmentHelper(oItem.download);
2041
					oAttachment.waiting(false).uploading(true).complete(false);
2042
2043
					this.attachments.push(oAttachment);
2044
				}
2045
			}
2046
		}
2047
	}
2048
};
2049
2050
ComposePopupView.prototype.removeLinkedAttachments = function()
2051
{
2052
	var arrachment = _.find(this.attachments(), function(oItem) {
2053
		return oItem && oItem.isLinked;
2054
	});
2055
2056
	if (arrachment)
2057
	{
2058
		this.attachments.remove(arrachment);
2059
		Utils.delegateRunOnDestroy(arrachment);
2060
	}
2061
};
2062
2063
ComposePopupView.prototype.setMessageAttachmentFailedDownloadText = function()
2064
{
2065
	_.each(this.attachments(), function(oAttachment) {
2066
		if (oAttachment && oAttachment.fromMessage)
2067
		{
2068
			oAttachment
2069
				.waiting(false)
2070
				.uploading(false)
2071
				.complete(true)
2072
				.error(Translator.getUploadErrorDescByCode(Enums.UploadErrorCode.FileNoUploaded));
2073
		}
2074
	}, this);
2075
};
2076
2077
/**
2078
 * @param {boolean=} bIncludeAttachmentInProgress = true
2079
 * @returns {boolean}
2080
 */
2081
ComposePopupView.prototype.isEmptyForm = function(bIncludeAttachmentInProgress)
2082
{
2083
	bIncludeAttachmentInProgress = Utils.isUnd(bIncludeAttachmentInProgress) ? true : !!bIncludeAttachmentInProgress;
2084
	var bWithoutAttach = bIncludeAttachmentInProgress ?
2085
		0 === this.attachments().length : 0 === this.attachmentsInReady().length;
2086
2087
	return 0 === this.to().length &&
2088
		0 === this.cc().length &&
2089
		0 === this.bcc().length &&
2090
		0 === this.replyTo().length &&
2091
		0 === this.subject().length &&
2092
		bWithoutAttach &&
2093
		(!this.oEditor || '' === this.oEditor.getData());
2094
};
2095
2096
ComposePopupView.prototype.reset = function()
2097
{
2098
	this.to('');
2099
	this.cc('');
2100
	this.bcc('');
2101
	this.replyTo('');
2102
	this.subject('');
2103
2104
	this.requestDsn(false);
2105
	this.requestReadReceipt(false);
2106
	this.markAsImportant(false);
2107
2108
	this.attachmentsPlace(false);
2109
2110
	this.aDraftInfo = null;
2111
	this.sInReplyTo = '';
2112
	this.bFromDraft = false;
2113
	this.sReferences = '';
2114
2115
	this.sendError(false);
2116
	this.sendSuccessButSaveError(false);
2117
	this.savedError(false);
2118
	this.savedTime(0);
2119
	this.emptyToError(false);
2120
	this.attachmentsInProcessError(false);
2121
2122
	this.showCc(false);
2123
	this.showBcc(false);
2124
	this.showReplyTo(false);
2125
2126
	Utils.delegateRunOnDestroy(this.attachments());
2127
	this.attachments([]);
2128
2129
	this.dragAndDropOver(false);
2130
	this.dragAndDropVisible(false);
2131
2132
	this.draftFolder('');
2133
	this.draftUid('');
2134
2135
	this.sending(false);
2136
	this.saving(false);
2137
2138
	if (this.oEditor)
2139
	{
2140
		this.oEditor.clear(false);
2141
	}
2142
};
2143
2144
/**
2145
 * @returns {Array}
2146
 */
2147
ComposePopupView.prototype.getAttachmentsDownloadsForUpload = function()
2148
{
2149
	return _.map(_.filter(this.attachments(), function(oItem) {
2150
		return oItem && '' === oItem.tempName();
2151
	}), function(oItem) {
2152
		return oItem.id;
2153
	});
2154
};
2155
2156
ComposePopupView.prototype.resizerTrigger = function()
2157
{
2158
	this.resizer(!this.resizer());
2159
};
2160
2161
module.exports = ComposePopupView;
2162